<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./js/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <App></App>
    </div>
  </body>
</html>
<script>
  /* 
    组件实例：
      1.每次创建一个组件最后会得到一个这个组件对应VueComponent构造函数
      2.当组件被注册并使用的时候，就会把这个VueComponent构造函数给实例化，得到一个实例化对象（组件实例化对象，组件实例）
      3.当前组件的数据，方法等等都会在自己的组件实例上存放

    一个重要的内置关系：
      问：想要给每一个组件实例扩展一个count属性，则给VueComponent.prototype.count设置是否所有的组件就有count属性了
      答：不是，因为每一个组件都有自己的VueComponent构造函数，并不是只有同一个VueComponent构造函数
      组件实例的原型链：组件实例==>当前组件的VueComponent构造函数的原型对象==>Vue构造函数的原型对象==>Object构造函数的原型对象==>null
      从上面原型链所看，VueComponent构造函数是继承了Vue构造函数（VueComponent.prototype.__proto__===Vue.prototype）
      得到结论：想要让所有的组件都能访问到一个属性，则我们需要把属性放在Vue.prototype上才可以
  */
  Vue.config.productionTip = false;

  Vue.prototype.$bus = 1;

  const Header = Vue.extend({
    name: 'Header',
    template: `
      <h2>我是头部Header</h2>
    `,
    mounted() {
      console.log(this.$bus, 'Header组件');
    },
  });

  const App = Vue.extend({
    name: 'App',
    components: {
      Header,
    },
    template: `
      <div>
        <h1>App {{message}}</h1>
        <Header></Header>
      </div>
    `,
    data() {
      return {
        message: 'hello',
      };
    },
    mounted() {
      console.log(this, 'App组件实例');
      console.log(this.__proto__, 'VueComponent构造函数的原型对象');
      console.log(this.__proto__.__proto__, 'VueComponent构造函数的原型对象');
      console.log(
        this.__proto__.__proto__.__proto__,
        'Object构造函数的原型对象'
      );
      console.log(this.__proto__.__proto__.__proto__.__proto__, 'Null');
      console.log(this.$bus, 'App组件');
    },
  });

  console.log(App, 'App'); // VueComponent构造函数

  const vm = new Vue({
    el: '#app',
    components: {
      App,
    },
    data() {
      return {};
    },
  });

  /*
    Vue内部的继承关系伪代码如下：
  */
  // class Vue {}

  // class VueComponent extends Vue {}

  // Vue.prototype.a = 1;
</script>
